#include "pch.hpp"
#include "Console.hpp"
#include "VerticalLayout.hpp"
//#include "as_exception.h"




Console::Console(Widget* parent, Widgets::Type finalType /*= Widgets::Console*/)
	: Widget(parent, finalType)
	, m_enabled(true)
	, m_lineEdit(new LineEdit(this, Widgets::LineEdit))
	, m_text(new Text("", this, Widgets::Text))
	, command(m_command)
{
	if(finalType == type())
		updateStyle();

	LayoutPtr layout = LayoutPtr(new VerticalLayout(this));
	setLayout(layout);

	// The text widget occupies all space, whereas the line-edit
	// only gets its line and nothing else
	m_text->setResizing(Resizing::Greedy);
	m_text->setVerticalAlignment(VAlignment::Bottom);

	layout->add(m_text);
	layout->add(m_lineEdit);

	//registerInterface(*m_scriptDevice);
}
///////////////////////////////////////////////////////////////////////////////////////////////////

Console::~Console()
{}
///////////////////////////////////////////////////////////////////////////////////////////////////




void Console::print(QString text)
{
	if(m_text->text().size())
		text = '\n' + text;

	m_text->appendText(text);
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void Console::print(const std::string& text)
{
	print(QString(text.c_str()));
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void Console::print(int nbr)
{
	print(QString::number(nbr));
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void Console::print(float nbr)
{
	print(QString::number(nbr));
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void Console::print(double nbr)
{
	print(QString::number(nbr));
}
///////////////////////////////////////////////////////////////////////////////////////////////////




void Console::setEnabled(bool enabled)
{
	m_enabled = enabled;
}
///////////////////////////////////////////////////////////////////////////////////////////////////




Widgets::Type Console::type() const
{
	return Widgets::Console;
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void Console::update(NestedState& state)
{
	Widget::update(state);

	const Cursor& cursor = state.cursor();
	if(cursor.keyPressed(Key::Enter) && m_lineEdit->caption().size())
	{
		// Interpret the current line as a command, also flush the
		// LineEdit and add the command (as well as subsequent output)
		// to the output
		QString cmd = m_lineEdit->caption();
		std::string errorBuffer;
		m_lineEdit->setCaption("");

		// Immediately add the command to the "history"
		print("> " + cmd);
		/*if(m_scriptDevice->executeString(qPrintable(cmd), errorBuffer) != IScriptContext::Finished && errorBuffer.size())
		{
			// Add compilation/execution errors to the history
			print(errorBuffer);
		}*/
	}

	if(m_enabled && cursor.keyClicked(Key::Tab))
	{
		if(!visible())
		{
			state.setModalWidget(this);
			state.setFocusWidget(m_lineEdit.get());
			setVisible(true);
		}
		else
		{
			state.unsetModalWidget(this);
			state.unsetFocusWidget(m_lineEdit.get());
			setVisible(false);
		}
	}
	else if(!m_enabled && visible())
	{
		state.unsetModalWidget(this);
		state.unsetFocusWidget(m_lineEdit.get());
		setVisible(false);
	}
}
///////////////////////////////////////////////////////////////////////////////////////////////////




/*
void Console::registerInterface(asIScriptEngine* engine)
{
	AS_API_CALL(engine->RegisterObjectType("Console", 0, asOBJ_REF));
	AS_API_CALL(engine->RegisterObjectBehaviour("Console", asBEHAVE_ADDREF, "void f()", asFUNCTION(addRef), asCALL_CDECL_OBJLAST));
	AS_API_CALL(engine->RegisterObjectBehaviour("Console", asBEHAVE_RELEASE, "void f()", asFUNCTION(release), asCALL_CDECL_OBJLAST));

	AS_API_CALL(engine->RegisterObjectMethod("Console", "void print(const string &in)", asMETHODPR(Console, print, (const std::string&), void), asCALL_THISCALL));
	AS_API_CALL(engine->RegisterObjectMethod("Console", "void print(int)", asMETHODPR(Console, print, (int), void), asCALL_THISCALL));
	AS_API_CALL(engine->RegisterObjectMethod("Console", "void print(float)", asMETHODPR(Console, print, (float), void), asCALL_THISCALL));
	AS_API_CALL(engine->RegisterObjectMethod("Console", "void print(double)", asMETHODPR(Console, print, (double), void), asCALL_THISCALL));

	AS_API_CALL(engine->RegisterGlobalProperty("Console console", this));
}
///////////////////////////////////////////////////////////////////////////////////////////////////
*/
